package org.apache.click.doubleclick.inject;

import org.apache.click.Context;
import org.apache.commons.lang.Validate;

/**
 * Inject aware implementation for non page file to use to inject dependencies.
 * If configured properly all click {@link org.apache.click.Page}'s dependencies are
 * injected when the page is instantiated. Which is not valid for non-{@link org.apache.click.Page}
 * classes. Non-{@link org.apache.click.Page} classes can extend this class to
 * inject dependencies when instantiated.
 * <p/>
 * If the class is already extending another class or user does not want to extend
 * any class for some specific reason, then they should use org.apache.click.doubleclick.inject.InjectAware.injectDependencies(Object)
 * <p/>
 * <p/>
 * <pre>
 * {@code
 *  class MyNonPageClass {
 *      public MyNonPageClass() {
 *          InjectAware.injectDependencies(this);
 *      }
 *  }
 * }
 * </pre>
 *
 * @author Jahid Shohel(development.jsh@gmail.com)
 * @see org.apache.click.doubleclick.inject.InjectAwarePage
 */
public class InjectAware {
    protected InjectAware() {
        injectDependencies(this);
    }

    public static void injectDependencies(Object target) {
        Validate.notNull(target, "Target can not be null");
        Validate.isTrue(Context.hasThreadLocalContext(), "Thread local context is not available");
        Object dependencyInjectorObj = Context.getThreadLocalContext().getServletContext().getAttribute(DependencyInjectorPageInterceptor.DEPENDENCY_INJECTOR);

        Validate.notNull(dependencyInjectorObj, "Dependency injector is null on servlet context");
        Validate.isTrue(dependencyInjectorObj instanceof DependencyInjector, "Invalid dependency injector. Expected " + DependencyInjector.class.getSimpleName() + ", but found " + dependencyInjectorObj.getClass().getSimpleName());

        DependencyInjector dependencyInjector = (DependencyInjector) dependencyInjectorObj;
        dependencyInjector.injectDependencies(target);
    }
}
